﻿using DataAccessObject;
using DataAccessObject.DAO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BUSINESS.Utils
{
    public class XepThoiKhoaBieu
    {
        private List<LOPHOC> listLopHoc;
        private List<MONHOC> listMonHoc;
        //private List<CHITIETMONHOC> listChiTietMonHoc;
        private List<GIAOVIEN> listGiaoVien;
        //private List<PHANCONG> listPhanCong;
        private Dictionary<int, LOPHOC> dicLopHoc;
        private Dictionary<int, GIAOVIEN> dicGiaoVien;
        private Dictionary<int, PHANCONG[]> tkbGiaoVien; // Thời khóa biểu của giáo viên

        public Dictionary<int, PHANCONG[]> TkbGiaoVien
        {
            get { return tkbGiaoVien; }
            set { tkbGiaoVien = value; }
        }
        private Dictionary<int, PHANCONG[]> tkbLopHoc;// Thời khóa biểu của lớp học

        public Dictionary<int, PHANCONG[]> TkbLopHoc
        {
            get { return tkbLopHoc; }
            set { tkbLopHoc = value; }
        }
        private int soTietTrongXepTKB;
        private int soTietTrongTuan; //Tinh them ca tiet sinh hoat thu 2 va thu 7

        public void Initilize()
        {
            listLopHoc = LopHocBUS.getAllLopHoc();
            listGiaoVien = GiaoVienBUS.getAllGiaoVien();
            listMonHoc = MonHocBUS.getAllMonHoc();
            soTietTrongXepTKB = 0;
            tkbGiaoVien = new Dictionary<int, PHANCONG[]>();
            tkbLopHoc = new Dictionary<int, PHANCONG[]>();
            foreach (MONHOC mh in listMonHoc)
            {
                soTietTrongXepTKB += (int)mh.SoTietTheoTuan;
            }
            soTietTrongTuan = soTietTrongXepTKB + 2;
            foreach (GIAOVIEN gv in listGiaoVien)
            {
                tkbGiaoVien[gv.UserId] = new PHANCONG[soTietTrongTuan];//chi so 0 va 25 dung de luu 2 tiet sinh hoat
            }
            foreach (LOPHOC lh in listLopHoc)
            {
                tkbLopHoc[lh.LopHocId] = new PHANCONG[soTietTrongTuan];// chi so 0 va 25 dung de luu Tiet dau va tiet cuoi la tiet sinh hoat 
            }

            
        }
        public void XepLop()
        {
            Initilize();
            Random random = new Random();
            foreach (LOPHOC lh in listLopHoc)
            {
                //Lấy list phân công của lớp đó
                List<PHANCONG> listPhanCong = PhanCongBUS.getPhanCongByLopHoc(lh);
                Dictionary<PHANCONG, int> kiemTraSoTietPhanCong = new Dictionary<PHANCONG, int>();
                List<GIAOVIEN> listGiaoVienPhanCong = GetGiaoVienFromPhanCong(listPhanCong);
                foreach (PHANCONG phancong in listPhanCong)
                {
                    kiemTraSoTietPhanCong[phancong] = 0;
                }

                for (int i = 1; i <= soTietTrongXepTKB; i++)
                {
                    //Đầu tiên loại bỏ những môn mà có giáo viên nào đã có tiết dạy trong giờ này
                    //Để vậy chúng ta sẽ kiểm tra trong hashGiaoVien
                    List<PHANCONG> listPhanCongGiaoVien;
                    List<PHANCONG> listTam = new List<PHANCONG>(listPhanCong);
                    foreach (GIAOVIEN gv in listGiaoVienPhanCong)
                    {
                        if (tkbGiaoVien[gv.UserId][i] != null)
                        {
                            //1 giáo viên có thể dạy nhiều môn
                            listPhanCongGiaoVien = GetPhanCongFromGiaoVien(gv, listPhanCong);
                            foreach (PHANCONG phancong in listPhanCongGiaoVien)
                            {
                                listTam.Remove(phancong);
                            }
                        }
                    }

                    int length = listTam.Count;
                    //Nếu còn môn chưa xếp thời khóa biểu
                    if (length > 0)
                    {
                        int rand = random.Next(length);
                        PHANCONG phancong = listTam[rand];
                        //Đánh dấu giáo viên của môn được chọn ở lớp này đã dạy vào tiết thứ i
                        GIAOVIEN gv = phancong.GIAOVIEN;
                        tkbGiaoVien[PhanCongDAO.GetGiaoVien(phancong).UserId][i] = phancong;

                        kiemTraSoTietPhanCong[phancong]++;                        
                        tkbLopHoc[lh.LopHocId][i] = phancong;
                        
                        //Kiểm tra nếu môn đó đủ số tiết thì loại khỏi list                        
                        if (kiemTraSoTietPhanCong[phancong] == (int)phancong.CHITIETMONHOC.MONHOC.SoTietTheoTuan)
                        {
                            listPhanCong.Remove(phancong);
                        }
                        
                    }
                    else
                    {
                        //chưa xếp thời khóa biểu được ở tiết thứ i
                        tkbLopHoc[lh.LopHocId][i] = null;
                    }

                }                
            }
        }

        private List<PHANCONG> GetPhanCongFromGiaoVien(GIAOVIEN gv, List<PHANCONG> listPhanCong)
        {
            List<PHANCONG> listPhanCongGiaoVien = new List<PHANCONG>();
            foreach (PHANCONG pc in listPhanCong)
            {
                GIAOVIEN giaoVien = PhanCongDAO.GetGiaoVien(pc);
                if (giaoVien.UserId == gv.UserId)
                {
                    listPhanCongGiaoVien.Add(pc);
                }
            }
            return listPhanCongGiaoVien;
        }

        private List<GIAOVIEN> GetGiaoVienFromPhanCong(List<PHANCONG> listPhanCong)
        {
            List<GIAOVIEN> listGiaoVienPhanCong = new List<GIAOVIEN>();
            foreach (PHANCONG pc in listPhanCong)
            {
                GIAOVIEN giaoVien = PhanCongDAO.GetGiaoVien(pc);
                listGiaoVienPhanCong.Add(giaoVien);
            }
            return listGiaoVienPhanCong;
        }
        //private GIAOVIEN GetGiaoVienfromChiTietMonHocLopHoc(CHITIETMONHOC chiTietMonHoc, LOPHOC lh)
        //{
        //    return null;
        //}

        //private PHANCONG GetPhanCongTuLopHocChiTietMonHoc(CHITIETMONHOC chiTietMonHoc, LOPHOC lh)
        //{
        //    return null;
        //}

        //private List<CHITIETMONHOC> GetChiTietMonHocTheoLop(LOPHOC lh)
        //{
        //    return null;
        //}

        //private CHITIETMONHOC GetChiTietMonHocFromGiaoVienandLopHoc(GIAOVIEN gv, LOPHOC lh)
        //{
        //    return null;
        //}
    }
}
